#ifndef _QUEUE_H_
#define _QUEUE_H_

#include <stddef.h>
#include <stdbool.h>
#include "slist.h"
#include "util.h"

#ifdef __cplusplus
extern "C" {
#endif

// 队列节点（复用 slist 的节点结构）
typedef struct _snode queue_node_t;

// 队列结构
typedef struct {
    queue_node_t *head;  // 队头指针
    queue_node_t *tail;  // 队尾指针
} queue_t;

/**
 * @brief 初始化队列
 * @param queue 队列指针
 */
static inline void queue_init(queue_t *queue) 
{
    queue->head = NULL;
    queue->tail = NULL;
}

/**
 * @brief 检查队列是否为空
 * @param queue 队列指针
 * @return true 为空，false 非空
 */
static inline bool queue_is_empty(queue_t *queue) 
{
    return (queue->head == NULL);
}

/**
 * @brief 入队（元素添加到队尾）
 * @param queue 队列指针
 * @param node 待添加的节点
 */
static inline void queue_enqueue(queue_t *queue, queue_node_t *node) 
{
    node->next = NULL;
    if (queue->tail == NULL) {
        queue->head = node;
        queue->tail = node;
    } else {
        queue->tail->next = node;
        queue->tail = node;
    }
}

/**
 * @brief 出队（移除并返回队头元素）
 * @param queue 队列指针
 * @return 队头节点指针（若队列为空返回 NULL）
 */
static inline queue_node_t *queue_dequeue(queue_t *queue) 
{
    if (queue_is_empty(queue)) {
        return NULL;
    }
    queue_node_t *node = queue->head;
    queue->head = node->next;
    if (queue->head == NULL) {
        queue->tail = NULL;
    }
    return node;
}

/**
 * @brief 查看队头元素（不移除）
 * @param queue 队列指针
 * @return 队头节点指针（若队列为空返回 NULL）
 */
static inline queue_node_t *queue_peek(queue_t *queue) 
{
    return queue->head;
}

// 通过队列节点获取外层容器
#define QUEUE_CONTAINER(node, type, member) \
    ((node) ? CONTAINER_OF((node), type, member) : NULL)

// 安全遍历队列的容器（允许在遍历时删除节点）
#define QUEUE_FOR_EACH_CONTAINER_SAFE(queue, cn, cns, member)               \
    for (cn = QUEUE_CONTAINER(queue_peek(queue), typeof(*cn), member),       \
         cns = (cn) ? QUEUE_CONTAINER((cn)->member.next, typeof(*cn), member) : NULL; \
         cn != NULL;                                                         \
         cn = cns, cns = (cn) ? QUEUE_CONTAINER((cn)->member.next, typeof(*cn), member) : NULL)

#ifdef __cplusplus
}
#endif

#endif /* _QUEUE_H_ */
